﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Kortex.AllCommandsSpace;
using Kortex.TCPClient;
using Kortex.Network_mapper;
using Kortex.Ident_manager;
using Kortex.WallMgr.NSL;
using Kortex.WallMgr;
using Kortex.WallManagerSpce.CubeManager;
using Newtonsoft.Json;
using Kortex.WallManagerControl.REST_Server;
using Barco.Web.KPHttpServer;
using System.IO;
using Tamir.SharpSsh.java.lang;
using System.Diagnostics;

namespace Kortex.Factory
{
    class Factory
    {
        
        public static void CreateAll(KortexGuiMain obj)
        {
            tcpCLient tcpClnt = null;
            CommandHandleKP Cmd = null;
            NetworkMapper Np = null;
            IdentManager idMgr = new IdentManager();
            Cmd = new CommandHandleKP(idMgr);
            
            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdFpgaService = Np;
            

            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdPanelService = Np;

            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdSysMgrService = Np;

            /*Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdVideoService = Np;
            */
            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdColorService = Np;


            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdInputService = Np;

            obj.AllCommands = Cmd;
            
        
        }

        public static void CreateAll(NSLcube obj)
        {
            tcpCLient tcpClnt = null;
            CommandHandleKP Cmd = null;
            NetworkMapper Np = null;
            IdentManager idMgr = new IdentManager();
            Cmd = new CommandHandleKP(idMgr);

            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdFpgaService = Np;


            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdPanelService = Np;

            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdSysMgrService = Np;

            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdVideoService = Np;


            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdInputService = Np;


            Np = new NetworkMapper(obj);
            tcpClnt = new tcpCLient(Np);
            Np.tcpClintIF = tcpClnt;
            Cmd.sdColorService = Np;

            obj.pubAllCommands = Cmd;


        }

        public static WallManager CreateWallManager(Int32 col_P, Int32 row_p, KortexGuiMain Root_gui,string input_p,string WallMode)
        {
            WallManager WallMg = null;
            RestServer rest = null;
            MyWebServer KpWebSer = null;
            
            WallMg = new WallManager(col_P, row_p, Root_gui, input_p, WallMode);

            rest = new RestServer(WallMg);
            KpWebSer = new MyWebServer(rest);
            WallMg.RestSrv = rest;
            rest.HttpServer = KpWebSer;
            

           // CubeGui cu = new CubeGui(WallMg);
           // WallMg.pubCube = cu;


            return WallMg;
        }

        static List<string> LoadedIps = new List<string>();
        static Dictionary<string, string> SerailVsIpMap = new Dictionary<string, string>();

        private static byte[] ReadFileIps(string file)
        {
            FileStream inStream = null;
            try
            {
                inStream = File.OpenRead(file);
            }
            catch (FileNotFoundException)
            {
                MessageBox.Show("File not found");
                return null;
            }
            catch (FileLoadException)
            {
                MessageBox.Show("File Load Exception");

                return null;
            }
            catch (DirectoryNotFoundException)
            {

                MessageBox.Show("Directory Not found");
                return null;

            }
            catch (FieldAccessException)
            {

                MessageBox.Show("FieldAccessException");
                return null;

            }
            catch (IOException er)
            {
                MessageBox.Show(er.Message);

                return null;

            }
            int count = 0;
            byte[] Buff = new Byte[inStream.Length];
            count = inStream.Read(Buff, 0, (Int32)inStream.Length);
            inStream.Close();
            //string sJSON = System.Text.ASCIIEncoding.ASCII.GetString(Buff);

            return Buff;

        }

        private static void RemoveDuplicate_and_white_space()
        {
             //List<string> LoadedIpsTemp = new List<string>();

            LoadedIps.Sort();
            Int32 index = 0;

                while (index < LoadedIps.Count - 1)
                {
                    /*if (LoadedIps[index] == string.Empty || LoadedIps[index].Length < 2)
                    {
                        LoadedIps.RemoveAt(index);
                        index++;
                    }
                     * */


                    if (LoadedIps[index] == LoadedIps[index + 1])
                        LoadedIps.RemoveAt(index);
                    else
                        index++;


                }

        }

        private static string GetSerial(string Inputdata)
        {
            int startIndex, endindex;
            string Serial = string.Empty;

            startIndex = Inputdata.LastIndexOf("[");
            endindex = Inputdata.LastIndexOf("]");

            if (startIndex > 0 && endindex > 0)
            {
                Serial = Inputdata.Substring((startIndex + 1), ((endindex - startIndex) - 1));
            }

            return Serial;

        }
  
        private static void init_IpVsSerialList()
        {
            string[] Data;
            string Ip;
            string restSerial;
            string RealSerial;

            SerailVsIpMap.Clear();

            for (int i = 0; i < LoadedIps.Count; i++)
            {
                Data = LoadedIps[i].Split('|');
                if (Data.Length > 1)
                {
                    Ip = Data[0];
                    restSerial = Data[1];
                    RealSerial = GetSerial(restSerial);
                    SerailVsIpMap[RealSerial] = Ip;
                }
            }
           

        }

        private static void LoadIpsFromFileToListBox(string FileName)
        {
           
           // string ToBeAssignIp = string.Empty;
           // bool bSerialWise = true;

            byte[] ips;
            ips = ReadFileIps(FileName);
            if (ips == null) return;
            string AllIps = System.Text.ASCIIEncoding.ASCII.GetString(ips);
            string[] SplitedIps = AllIps.Split('\n');

            LoadedIps.Clear();
            
            for (int i = 0; i < SplitedIps.Length; i++)
                LoadedIps.Add(SplitedIps[i].Trim());

            RemoveDuplicate_and_white_space();
            init_IpVsSerialList();

        }

        private static void FindAndSetCurrentIps(NSLcube[] dummyCube, string localDir)
        {
            string cmd = string.Empty;
            string exe = string.Empty;
            bool returnVal;
            
            Int32 waitTime = 6;
            string outputFIle = "OVD_KVD_IP.txt";
            string Ip_file = localDir + "\\" + outputFIle;

            //LoadIpsFromFileToListBox(Ip_file);
            //return; //Only for Debug other's Wall Config Files

            exe = localDir + "\\OVD_KVD_Browser.exe";
            cmd = "-w  " + waitTime.ToString();


            FileInfo MyFile = new FileInfo(Ip_file);
            if (MyFile.Exists)
            {
                MyFile.Delete();
                Thread.Sleep(1000);
                //Delay(200);
            }

            System.Diagnostics.ProcessStartInfo Input = new ProcessStartInfo(@exe, cmd);
            Input.CreateNoWindow = true;
            Input.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            System.Diagnostics.Process kp = System.Diagnostics.Process.Start(Input);


            returnVal = kp.WaitForExit(waitTime * 1000);

            MyFile = new FileInfo(Ip_file);
            if (!MyFile.Exists)
            {
                MessageBox.Show("Failed to Search IPs Please check if ZeroConf Utility install and running");
                return;
                //MyFile.Delete();
                //Delay(200);
            }

            LoadIpsFromFileToListBox(Ip_file);



        
        }

        public static WallManager CreateWallManagerSerialWise(string WallJson, KortexGuiMain Root_gui)
        {
            int i;
            WallManager WallMg = null;
            RestServer rest = null;
            MyWebServer KpWebSer = null;
            NSLcube []dummyCube = null;
            string[] AllCube = WallJson.Split("\n".ToCharArray());

            dummyCube = new NSLcube[AllCube.Length-1];

            for ( i = 0; i < AllCube.Length - 1;i++ )
                dummyCube[i] = JsonConvert.DeserializeObject<NSLcube>(AllCube[i]);
            try
            {
                WallMg = new WallManager(dummyCube[0].mXmax, dummyCube[0].mYmax, Root_gui, dummyCube[0].wallConfInput, dummyCube[0].wallConfMode);
            }
            catch(Exception er)
            {
                
                return null;
            
            }

            rest = new RestServer(WallMg);
            WallMg.RestSrv = rest;
            KpWebSer = new MyWebServer(rest);
            rest.HttpServer = KpWebSer;

            FindAndSetCurrentIps(dummyCube, Root_gui.localDir);
            // CubeGui cu = new CubeGui(WallMg);
            // WallMg.pubCube = cu;

            for (i = 0; i < AllCube.Length - 1; i++)
            {
                try
                {
                    if (dummyCube[i].mDispSerialNumber != string.Empty)
                        WallMg.SetCubeValues(dummyCube[i].pos_Col, dummyCube[i].pos_Row, SerailVsIpMap[dummyCube[i].mDispSerialNumber], dummyCube[i].mMacAddress1, dummyCube[i].mMacAddress2, dummyCube[i].mDispSerialNumber);
                }
                catch(Exception er)
                {
                
                }
            }






            return WallMg;
        }

        public static WallManager CreateWallManager(string WallJson, KortexGuiMain Root_gui)
        {
            int i;
            
            WallManager WallMg = null;
            RestServer rest = null;
            MyWebServer KpWebSer = null;
            NSLcube[] dummyCube = null;

            string[] AllCube = WallJson.Split("\n".ToCharArray());

            dummyCube = new NSLcube[AllCube.Length - 1];

            for (i = 0; i < AllCube.Length - 1; i++)
                dummyCube[i] = JsonConvert.DeserializeObject<NSLcube>(AllCube[i]);

            try
            {
                WallMg = new WallManager(dummyCube[0].mXmax, dummyCube[0].mYmax, Root_gui, dummyCube[0].wallConfInput, dummyCube[0].wallConfMode);
            }
            catch (Exception er)
            {
                return null;
            
            }

            rest = new RestServer(WallMg);
            WallMg.RestSrv = rest;
            KpWebSer = new MyWebServer(rest);
            rest.HttpServer = KpWebSer;

            // CubeGui cu = new CubeGui(WallMg);
            // WallMg.pubCube = cu;

            for (i = 0; i < AllCube.Length - 1; i++)
            {
                if (dummyCube[i].mIp != "")
                    WallMg.SetCubeValues(dummyCube[i].pos_Col, dummyCube[i].pos_Row, dummyCube[i].mIp, dummyCube[i].mMacAddress1, dummyCube[i].mMacAddress2);
            }






            return WallMg;
        }



    }
}
